package relu.fbs.xt;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import relu.fbs.BadDataException;
import relu.fbs.FarmData;
import relu.fbs.xt.FBSCropData.FBSCDatum;
import relu.fbs.xt.FBSFarmData.FBSFarmDatum;

public class FBS8387DataReader extends AbstractMultipleFileDataReader {

	enum FileType {
		A,
		LABOUR,
		CROPS;
	}
	
	static Map<Integer,FBSFarmData> read87Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.A, "F672A.tab");
		fileMap.put(FileType.LABOUR, "F672C.tab");
		fileMap.put(FileType.CROPS, "F672E.tab");
		return readData(fileMap,1);
	}
	
	static Map<Integer,FBSFarmData> read86Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.A, "F384A.tab");
		fileMap.put(FileType.LABOUR, "F384C.tab");
		fileMap.put(FileType.CROPS, "F384E.tab");
		return readData(fileMap,1);
	}

	static Map<Integer,FBSFarmData> read85Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.A, "F383A.tab");
		fileMap.put(FileType.LABOUR, "F383C.tab");
		fileMap.put(FileType.CROPS, "F383E.tab");
		return readData(fileMap,1);
	}
	static Map<Integer,FBSFarmData> read84Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.A, "F241A.tab");
		fileMap.put(FileType.LABOUR, "F241C.tab");
		fileMap.put(FileType.CROPS, "F241E.tab");
		return readData(fileMap,1);
	}
	
	static Map<Integer,FBSFarmData> readData(Map<FileType,String> fileNames,int yc) throws FileNotFoundException, IOException ,NumberFormatException,BadDataException {
		Map<Integer,FBSFarmData> farms = generateFarms(fileNames.get(FileType.A),yc);
		
		String filetmp="";
		try {
		for(Map.Entry<FileType, String> file:fileNames.entrySet()){
			filetmp=file.getValue();
			FileType fn = file.getKey();
			System.out.println("Processing "+fn);
			switch(fn){
			case A:
				addAData(file.getValue(),farms,yc);
				break;
			case LABOUR:
				addLabourData(file.getValue(),farms,yc);
				break;
			case CROPS:
				addCropsData(file.getValue(),farms,yc);
				break;
			default:
				System.out.println("Skipped");
			}
		}				
		} catch (NumberFormatException ex){
			throw new NumberFormatException("Number format exception in file: "+filetmp+" "+ex.getMessage());
		}
		return farms;
	}
	
	static void addCropsData(String fileName,Map<Integer,FBSFarmData> farms,int yrcode) throws FileNotFoundException, IOException ,NumberFormatException,BadDataException {
		FileReader reader=new FileReader(fileName);
		BufferedReader buffrd=new BufferedReader(reader);

		String line = buffrd.readLine(); // Read the header 
		line=buffrd.readLine();
		while( line!=null){
			String[] colStrings=line.split("\t");
			int ycode=Integer.parseInt(colStrings[3]);
			if ( ycode==yrcode){
				int farmid = Integer.parseInt(colStrings[14]);				
				FBSFarmData theFarm=farms.get(farmid);

				int cropType = Integer.parseInt(colStrings[0]);
				double mainArea=Double.parseDouble(colStrings[4]);
				double multArea=Double.parseDouble(colStrings[5]);
				double subsidies=Double.parseDouble(colStrings[10]);
				double eo=Double.parseDouble(colStrings[11]);
				if ( FarmData.fbsTotalCodes.contains(cropType)){
//					System.out.println(cropType+" :"+farmid+" yc "+ycode+":"+yrcode);
					FBSDataReader.addSectionCTotal(theFarm, 
							new FBSPost2000DataPoint(farmid,'C',cropType,21,10,0),mainArea);
					FBSDataReader.addSectionCTotal(theFarm, 
							new FBSPost2000DataPoint(farmid,'C',cropType,40,10,0),subsidies);
					FBSDataReader.addSectionCTotal(theFarm, 
							new FBSPost2000DataPoint(farmid,'C',cropType,41,10,0),eo);
				} else {
//					System.out.println(farmid+" "+farms.containsKey(farmid));
					FBSCropData cropd = farms.get(farmid).getCrop(FarmData.getCheckedCropType(cropType));
				
					cropd.setDatum(FBSCDatum.AREA, mainArea, new FBSPost2000DataPoint(farmid,'C',cropType,-1,10,0));
					cropd.setDatum(FBSCDatum.MAREA, multArea, new FBSPost2000DataPoint(farmid,'C',cropType,-1,10,0));
//				double revXsubs=Double.parseDouble(colStrings[9]);
//				double farmCons=Double.parseDouble(colStrings[10]);
					cropd.setDatum(FBSCDatum.AREAPAYMENT, subsidies, new FBSPost2000DataPoint(farmid,'C',cropType,-1,10,0));
					cropd.setDatum(FBSCDatum.EO, eo, new FBSPost2000DataPoint(farmid,'C',cropType,-1,10,0));
				}
			}
			line=buffrd.readLine();
		}
	}

	static void addAData(String fileName,Map<Integer,FBSFarmData> farms,int yrcode) throws FileNotFoundException, IOException ,NumberFormatException,BadDataException {
		FileReader reader=new FileReader(fileName);
		BufferedReader buffrd=new BufferedReader(reader);

		String line = buffrd.readLine(); // Read the header 
		line=buffrd.readLine();
		Map<Integer,FBSFarmDatum> columnMap=new HashMap<Integer,FBSFarmDatum>();
		while( line!=null){
//			System.out.println(line);
			String[] colStrings=line.split("\t");
//			try {
			int ycode=Integer.parseInt(colStrings[3]);
			if ( ycode==yrcode){
				double region=Double.parseDouble(colStrings[0]);
				double county=Double.parseDouble(colStrings[1]);
				int farmid = Integer.parseInt(colStrings[2]);
				int Altitude=Integer.parseInt(colStrings[11]);
				int fob = Integer.parseInt(colStrings[7]);
				double tmsa=Double.parseDouble(colStrings[15]);
				double totalGrass=Double.parseDouble(colStrings[16]);
				double utilizedArea=Double.parseDouble(colStrings[17]);
				double nfincome = Double.parseDouble(colStrings[114]);
				if ( !colStrings[104].contentEquals(" ")){				
					double mainEO = Double.parseDouble(colStrings[104]);
					setCheckedDatum(farms,farmid,FBSFarmDatum.TOTALMAINEO,mainEO);
				}
				setDatum(farms,farmid,FBSFarmDatum.ALTITUDE,(double)Altitude);
				setDatum(farms,farmid,FBSFarmDatum.TOTALMAINSETASIDE,tmsa);
				setDatum(farms,farmid,FBSFarmDatum.TOTALGRASS,totalGrass);
				setDatum(farms,farmid,FBSFarmDatum.UTILIZEDAREA,utilizedArea);
				setDatum(farms,farmid,FBSFarmDatum.NETFARMINCOME,nfincome);
				setDatum(farms,farmid,FBSFarmDatum.FORMOFBUSINESS,fob);
				setDatum(farms,farmid,FBSFarmDatum.REGION,(double)region);
				setDatum(farms,farmid,FBSFarmDatum.COUNTY,(double)county);

			}

//			} catch (NumberFormatException ex ){
//				throw new Error(":"+colStrings[39]+":");
//			}
			line=buffrd.readLine();
		}
	}
	
	static Map<Integer,FBSFarmData> generateFarms(String file,int yrcode) throws FileNotFoundException, IOException ,NumberFormatException, BadDataException {
		System.out.println("Generating Farms");
		Map<Integer,FBSFarmData> farms=new HashMap<Integer,FBSFarmData>(); 
		FileReader reader=new FileReader(file);
		BufferedReader buffrd=new BufferedReader(reader);
		String line = buffrd.readLine(); // Read the header 
		line=buffrd.readLine();
		while( line!=null){
			String[] colStrings=line.split("\t");
			int farmid=Integer.parseInt(colStrings[2]);
			int ycode=Integer.parseInt(colStrings[3]);
			if (ycode==yrcode){
				if ( farms.containsKey(farmid)){
					throw new Error("Only one copy of each farm is allowed ");
				}
				FBSFarmData theFarm=new FBSFarmData(farmid);
				theFarm.putFarmData(FBSFarmDatum.FARMID, (double)farmid);
				farms.put(farmid, theFarm);
			}
			line=buffrd.readLine();
		}
		return farms;
	}
}
